package com.songlanyun.modules.order.service.impl.coupon.shopcoupon;

import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.coupon.model.vo.CouponEntityVo;
import com.songlanyun.modules.coupon.model.vo.CouponReceiveRecordVo;
import com.songlanyun.modules.coupon.service.CouponReceiveRecordService;
import com.songlanyun.modules.coupon.service.CouponService;
import com.songlanyun.modules.order.model.dto.SubmitOrderUseCoupon;
import com.songlanyun.modules.order.model.vo.SubmitChildOrderVo;
import com.songlanyun.modules.order.model.vo.SubmitShopOrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service("seckillOrderUseShopCouponService")
public class SeckillOrderUseShopCouponImpl implements IUseShopCouponService {
    @Autowired
    private CouponReceiveRecordService couponReceiveRecordService;

    @Autowired
    private CouponService couponService;

    @Override
    public SubmitShopOrderVo handleShopCoupon(Long userId, SubmitShopOrderVo submitShopOrderVo) {

        /**
         * 查出我领取的店铺券,
         * 1、对应的店铺，
         * 2、店铺券，
         * 3、可以使用的，
         * 4、按面额排倒倒叙面额大的排前面，
         * 5、按门槛值排正序，门槛低的排前面，
         * 6、按通用券排正序，通用券排进面
         */
        if(submitShopOrderVo.getShopCoupon().getMyCouponId()==0L) {
            /**
             * 系统取优惠券
             */
            List<CouponReceiveRecordVo> couponEntityVos = couponReceiveRecordService.loadMyShopCoupons(userId, submitShopOrderVo.getShopId());
            for (CouponReceiveRecordVo couponEntityVo : couponEntityVos) {
                if (handle(submitShopOrderVo, couponEntityVo)) {
                    return submitShopOrderVo;
                }
            }
        }
        else
        {
            /**
             * 手动取优惠券
             */
            CouponReceiveRecordVo couponEntityVo = couponReceiveRecordService.loadByCouponSlimEntity(submitShopOrderVo.getShopCoupon().getMyCouponId(), true);
            handle(submitShopOrderVo, couponEntityVo);
        }




        return submitShopOrderVo;
    }

    private boolean handle(SubmitShopOrderVo submitShopOrderVo, CouponReceiveRecordVo couponEntityVo) {
        if(!couponEntityVo.isAdaptSecKill())
        {
            return false;
        }
        if (couponEntityVo.getUniversal()) {
            if (generalCouponHandle(couponEntityVo, submitShopOrderVo)) {
                return true;
            }
        } else {
            if (notGeneralCouponHandle(couponEntityVo, submitShopOrderVo)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 通用券算法
     *
     * @param couponEntityVo
     * @param submitShopOrderVo
     * @return
     */
    private Boolean generalCouponHandle(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo) {
        if (!couponEntityVo.getHasThreshold()) {
            return noHasThresholdGeneral(couponEntityVo, submitShopOrderVo);
        } else {
            return hasThresholdGeneral(couponEntityVo, submitShopOrderVo);
        }
    }

    /**
     * 非通用券算法
     *
     * @param couponEntityVo
     * @param submitShopOrderVo
     * @return
     */
    private Boolean notGeneralCouponHandle(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo) {
        if (!couponEntityVo.getHasThreshold()) {
            return noHasThresholdNotGeneral(couponEntityVo, submitShopOrderVo);
        } else {
            return hasThresholdNotGeneral(couponEntityVo, submitShopOrderVo);
        }
    }


    /**
     * 无门槛的通用算法
     *
     * @param couponEntityVo
     * @param submitShopOrderVo
     * @return
     */
    private Boolean noHasThresholdGeneral(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo) {
        childOrderSharingCompute(couponEntityVo, submitShopOrderVo, submitShopOrderVo.getItems(), submitShopOrderVo.getTotalGoodsAmount());
        return true;
    }


    /**
     * 有门槛的通用券算法
     *
     * @param couponEntityVo
     * @param submitShopOrderVo
     * @return
     */
    private Boolean hasThresholdGeneral(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo) {
        if (submitShopOrderVo.getTotalGoodsAmount().compareTo(couponEntityVo.getThreshold()) < 0) {
            return false;
        }
        return noHasThresholdGeneral(couponEntityVo, submitShopOrderVo);
    }


    /**
     * 无门槛的非通用券算算法
     *
     * @param couponEntityVo
     * @param submitShopOrderVo
     * @return
     */
    private Boolean noHasThresholdNotGeneral(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo) {
        List<SubmitChildOrderVo> adaptChildOrderVos = new ArrayList<>();

        BigDecimal totalGoodsAmount = getTotalGoodsAmount(couponEntityVo,submitShopOrderVo,adaptChildOrderVos);
        if(totalGoodsAmount.compareTo(BigDecimal.ZERO)==0)
        {
            return false;
        }
        childOrderSharingCompute(couponEntityVo, submitShopOrderVo, adaptChildOrderVos, totalGoodsAmount);
        return true;
    }

    /**
     * 有门槛的非通用券算法
     *
     * @param couponEntityVo
     * @param submitShopOrderVo
     * @return
     */
    private Boolean hasThresholdNotGeneral(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo) {

        List<SubmitChildOrderVo> adaptChildOrderVos = new ArrayList<>();
        BigDecimal totalGoodsAmount = getTotalGoodsAmount(couponEntityVo,submitShopOrderVo,adaptChildOrderVos);
        if(totalGoodsAmount.compareTo(BigDecimal.ZERO)==0)
        {
            return false;
        }

        if (totalGoodsAmount.compareTo(couponEntityVo.getThreshold()) < 0) {
            return false;
        }
        childOrderSharingCompute(couponEntityVo, submitShopOrderVo, adaptChildOrderVos, totalGoodsAmount);
        return true;
    }


    private BigDecimal getTotalGoodsAmount(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo,List<SubmitChildOrderVo> adaptChildOrderVos)
    {
        Map<Long, SubmitChildOrderVo> childOrderGroups = submitShopOrderVo.getItems().stream().collect(Collectors.toMap(SubmitChildOrderVo::getGoodsId, vo -> vo));
        Set<Long> childOrderGoodsIds = childOrderGroups.keySet();
        List<Long> adaptGoodsIds = couponEntityVo.loadAdaptGoodsIds();
        if (couponEntityVo.getAdaptOrNo()) {
            childOrderGoodsIds.retainAll(adaptGoodsIds);

        } else {
            childOrderGoodsIds.removeAll(adaptGoodsIds);
        }

        BigDecimal totalGoodsAmount = BigDecimal.ZERO;
        for (Long goodsId : childOrderGoodsIds) {
            SubmitChildOrderVo submitChildOrderVo = childOrderGroups.get(goodsId);
            adaptChildOrderVos.add(submitChildOrderVo);
            totalGoodsAmount = MathUtils.add(submitChildOrderVo.getTotalPrice(), totalGoodsAmount);
        }
        return totalGoodsAmount;
    }



    private void childOrderSharingCompute(CouponReceiveRecordVo couponEntityVo, SubmitShopOrderVo submitShopOrderVo, List<SubmitChildOrderVo> adaptChildOrderVos, BigDecimal totalGoodsAmount) {
        BigDecimal faceValue = couponEntityVo.getFaceValue();
        BigDecimal resultCouponValue = faceValue;
        if (faceValue.compareTo(totalGoodsAmount) >= 0) {
            resultCouponValue = totalGoodsAmount;
        }
        /**
         * 计算店铺优惠券的总情况
         */
        submitShopOrderVo.setShopCoupon(SubmitOrderUseCoupon.builder()
                .myCouponId(couponEntityVo.getId())
                .couponId(couponEntityVo.getCouponId())
                .couponName(couponEntityVo.getName())
                .couponFaceValue(couponEntityVo.getFaceValue())
                .couponResultValue(resultCouponValue)
                .build());

        adaptChildOrderVos.get(0).setShopCouponSharing(resultCouponValue);
    }

}
